import pymel.util.path as pmp
import maya.cmds as cmds
import maya.mel as mel
import maya.OpenMayaUI as OpenMayaUI
import shiboken
import os
import shutil
from PySide import QtGui, QtCore
from xml.dom.minidom import parse

class FBXExplorerQtWindow(QtGui.QMainWindow):
	def __init__(self,parent=None):
		super(FBXExplorerQtWindow,self).__init__(parent)
		self.setWindowTitle('MMD4Mecanim Import v0.1')
		self.resize( 800, 800 )
		
		widget = QtGui.QWidget()
		self.setCentralWidget(widget)
		
		mainLayout = QtGui.QVBoxLayout()
		widget.setLayout(mainLayout)
		
		self.line = QtGui.QLineEdit(self)
		self.fileBrowserWidget = QtGui.QWidget(self)
		self.dirModel = QtGui.QFileSystemModel()
		self.dirModel.setRootPath("C:/")
		
		nameFilters = ["*.fbx"]
		self.dirModel.setNameFilters(nameFilters)
		self.dirModel.setNameFilterDisables(False)
		
		self.folderView = QtGui.QTreeView(parent=self)
		self.folderView.setModel(self.dirModel)
		self.folderView.clicked[QtCore.QModelIndex].connect(self.clicked) 
		self.folderView.doubleClicked[QtCore.QModelIndex].connect(self.doubleClicked) 
		
		self.folderView.setColumnWidth(0,250)
		
		mainLayout.addWidget(self.line,1,0)
		mainLayout.addWidget(self.folderView)

	def clicked(self,index):
		index = self.folderView.currentIndex()
		dirPath = pmp(self.dirModel.filePath(index))
		self.line.setText(dirPath.normpath())

	def doubleClicked(self,index):
		index = self.folderView.currentIndex()
		path = pmp(self.dirModel.filePath(index))
		self.openFile(path)

	def openFile(self,filePath):
		types = {".fbx":"FBX"}
		if filePath.ext.lower() not in types.keys():
			return
		fileType = types[filePath.ext.lower()]
		if fileType == "FBX":
			nPos = filePath.rfind('/')
			dirPath = filePath[0:nPos+1]
			fileName = filePath[nPos+1:filePath.rfind('.')]
			fbxFileName = filePath[nPos+1:len(filePath)]
			xmlFileName = fileName + '.xml'
			xmlFilePath = dirPath + xmlFileName
			newDirPath = self.copyFileForMaya(fileName, filePath, xmlFilePath, dirPath)
			
			if os.path.exists(newDirPath):
				newFbxFilePath = newDirPath + fbxFileName
				newXmlFilePath = newDirPath + xmlFileName
				self.processRename(newFbxFilePath, newXmlFilePath)
				self.importFBXFile(newFbxFilePath)
				self.importTexture(newXmlFilePath, newDirPath)
				shutil.rmtree(newDirPath,True)
			return

	def copyFileForMaya(self, fbxFileName, fbxFilePath, xmlFilePath, dirPath):
		newDirName = '.temp_' + fbxFileName
		newDirPath = os.path.join(dirPath, newDirName)
		if not os.path.isdir(newDirPath):
			os.makedirs(newDirPath)
		
		newDirPath += '/'	
		if not os.path.exists(newDirPath):
			print newDirPath + ' does not exist!'
			return ''
		
		shutil.copy(fbxFilePath, newDirPath)
		shutil.copy(xmlFilePath, newDirPath)
		return newDirPath

	def modify(self, filePath, sourceStr, targetStr):
		print 'modify ' + filePath + ' from ' + sourceStr + ' to ' + targetStr
		inputFile = open(filePath)
		lines = inputFile.readlines()
		inputFile.close()

		outputFile = open(filePath, 'w')
		for line in lines:
			if not line:
				break
			if sourceStr in line and not targetStr in line:
				nPos = line.find(sourceStr)
				temp1 = line[0:nPos]
				temp2 = line[nPos+len(sourceStr):len(line)]
				temp = temp1 + targetStr + temp2
				outputFile.write(temp)
			else:
				outputFile.write(line)

		outputFile.close()

	def formatName(self, name):
		newName = ''
		if '.' in name:
			nPos = name.find('.')
			newName = 'mat_' + name[0:nPos]
		else:
			newName = 'mat_' + name
		return newName
		
	def modifyMaterialName(self, fbxFilePath):
		inputFbxFile = open(fbxFilePath)
		inputFbxLines = inputFbxFile.readlines()
		inputFbxFile.close()
		outputFbxFile = open(fbxFilePath, 'w')
		tag1 = 'Material::'
		tag2 = ';Material::'
		for line in inputFbxLines:
			if not line:
				break
			if tag2 in line:
				nPos1 = line.find(tag2)
				temp1 = line[0:nPos1]
				temp2 = line[nPos1+len(tag2):len(line)]
				nPos2 = temp2.find(', Model::')
				temp3 = temp2[nPos2:len(temp2)]
				materialName = self.formatName(temp2[0:nPos2])
				temp = temp1 + tag2 + materialName + temp3
				outputFbxFile.write(temp)
			elif tag1 in line:
				nPos1 = line.find(tag1)
				temp1 = line[0:nPos1]
				temp2 = line[nPos1+len(tag1):len(line)]
				nPos2 = temp2.find('"')
				temp3 = temp2[nPos2:len(temp2)]
				materialName = self.formatName(temp2[0:nPos2])
				temp = temp1 + tag1 + materialName + temp3
				outputFbxFile.write(temp)
			else:
				outputFbxFile.write(line)
		outputFbxFile.close()
		
	def processRename(self, fbxFilePath, xmlFilePath):
		self.modifyMaterialName(fbxFilePath)
		self.modify(xmlFilePath, '<materialName>', '<materialName>mat_')
		self.modify(xmlFilePath, '<fileName>', '<fileName>../')
		print 'Material rename completed!'

	def importFBXFile(self, filePath):
		nPos = filePath.rfind('/')
		fileName = filePath[nPos+1:filePath.rfind('.')]
		importedFile = cmds.file(filePath, i=True, type='FBX', ignoreVersion=True, ra=True, rdn=True, mergeNamespacesOnClash=False, namespace=fileName)
		print importedFile + ' import completed!'
	
	def importTexture(self, filePath, dirPath):
		dom = parse(filePath)
		
		texFileNames = dom.getElementsByTagName("fileName")
		textures = []
		for i, texFileName in enumerate(texFileNames) :
			textures.append(dirPath.encode('shift-jis') + texFileName.childNodes[0].data.encode('shift-jis'))
			if cmds.objExists('file' + str(i+1)) :
				continue
			else:
				fileNode = cmds.shadingNode('file', asTexture=True)
				cmds.setAttr(fileNode + '.fileTextureName', textures[i], type="string")
		print textures
		
		materialNames = dom.getElementsByTagName("materialName")	
		materialID = []
		for i, materialName in enumerate(materialNames) :
			materialID.append(materialName.childNodes[0].data)
		print materialID
		
		textureIDs = dom.getElementsByTagName("textureID")
		materialTexID = []
		for i, textureID in enumerate(textureIDs) :
			materialTexID.append(textureID.childNodes[0].data)
		print materialTexID
		
		for i, iMatID in enumerate(materialID) :
			iTexID = int(materialTexID[int(i)])+1
			if(iTexID <= 0):
				continue
			try:
				cmds.connectAttr('file%s.outColor' %iTexID, '%s.color' %iMatID)
				print iMatID
			except:
				continue

def show_explorer(*args):
	ptr = OpenMayaUI.MQtUtil.mainWindow()
	widget = shiboken.wrapInstance(long(ptr),QtGui.QWidget)
	explorerWin = FBXExplorerQtWindow(widget)
	explorerWin.show()

def show_help(*args):
	cmds.confirmDialog(title = "Help", message = "\
Steps to import:\n\
1. Convert PMD/PMX file to FBX file in unity by using MMD4Mecanim.\n\
2. Click 'MMD4Mecanim Import' to browse the FBX file of step1, double click to import.\n\
3. In MotionBuilder, click 'File/open' to import the FBX file of step1 with default configuration (recommend to uncheck the material).\n\
4. In MotionBuilder, select the skeleton (or all the model) you imported at step3, click 'File/Send to Maya/Update Current Scene'.\n\
\n\
Attention:\n\
1. The file name of fbx file and texture files should not be japanese or chinese.\n\
2. You can only import one model at a time, please save your model as the standard fbx file, then create a new scene to import another one.\n\
\n\
Enjoy! >_< \n\
\n\
Author: Takamachi Marisa\n\
Contact: http://weibo.com/u/2832212042",\
	icon = "information")

def customMayaMenu():
	gMainWindow = mel.eval('$temp1=$gMainWindow')
	menus = cmds.window(gMainWindow, q = True, menuArray = True)
	found = False
	
	for menu in menus:
		label = cmds.menu(menu, q = True, label = True)
		if label == "MMD4Mecanim Import":
			found = True
	
	if found == False:
		customMenu = cmds.menu(parent=gMainWindow, label = 'MMD4Mecanim Import')
		cmds.menuItem(parent = customMenu, label = "Import MMD4Mecanim FBX", c = show_explorer)
		cmds.menuItem(parent = customMenu, label = "Help", c = show_help)

# Initialize the plug-in
def initializePlugin(plugin):
	customMayaMenu()

# Uninitialize the plug-in
def uninitializePlugin(plugin):
	pass

